#include <gtest/gtest.h>
#include "BigInt/BigInt.h"

// Demonstrate some basic assertions.
TEST(AddTest, ZeroAdd) {
  

  // 0 + 0
  BigInt a(0);
  BigInt b(0);
  a.Add(b);
  EXPECT_STREQ(a.toString().c_str(), "0");

  // neg + 0
  BigInt a1(-2);
  BigInt b1(0);
  a1.Add(b1);
  EXPECT_STREQ(a1.toString().c_str(), "-2");

  // 0 + neg
  BigInt a2(0);
  BigInt b2(-102);
  a2.Add(b2);
  EXPECT_STREQ(a2.toString().c_str(), "-102");

  // pos + 0
  BigInt a3(1999);
  BigInt b3(0);
  a3.Add( b3 );
  EXPECT_STREQ(a3.toString().c_str(), "1999");


  // 0 + pos
  BigInt a4(0);
  BigInt b4(99);
  a4.Add(b4);
  EXPECT_STREQ(a4.toString().c_str(), "99");


  // 0 + big pos
  BigInt a5(0);
  BigInt b5("123456860051231321");
  a5.Add(b5);
  EXPECT_STREQ( a5.toString().c_str(), b5.toString().c_str() );

  // 0 + big neg
  BigInt a6(0);
  BigInt b6("-222222222222222222222223333333333333333333444444444444444555555555555555");
  a6.Add(b6);
  EXPECT_STREQ( a6.toString().c_str(), b6.toString().c_str() );

  // big pos + 0
  BigInt a7("12345678910987654321");
  BigInt b7(0);
  a7.Add(b7);
  EXPECT_STREQ( a7.toString().c_str(), "12345678910987654321");

  // big neg + 0
  BigInt a8("12345678910987654321");
  BigInt b8(0);
  a8.Add(b8);
  EXPECT_STREQ( a8.toString().c_str(), "12345678910987654321");
  
}

TEST(AddTest, SameFlagAdd) {
 

  // pos + pos

  BigInt a(81);
  BigInt b(919);

  a.Add(b);
  EXPECT_STREQ(a.toString().c_str(), "1000");

  BigInt a1(29);
  BigInt b2(92);
  
  a1.Add(b2);
  EXPECT_TRUE(a1.toString() == std::string("121"));


  // neg + neg

  BigInt a01(-2);
  BigInt b01(-3333);
  a01.Add(b01);
  EXPECT_STREQ(a01.toString().c_str(), "-3335");


  BigInt a02( -199);
  BigInt b02( -1);
  a02.Add(b02);
  EXPECT_TRUE(a02.toString() == std::string( "-200"));


  // zero + zero
  BigInt z0(0);
  BigInt z1(0);
  z0.Add(z1);
  EXPECT_TRUE( z0.toString() == std::string("0") );


  // big pos + big pos
  BigInt a10("24680135790123");
  BigInt b10("99999999995678");
  a10.Add( b10 );
  EXPECT_TRUE( a10.toString() == std::string("124680135785801") );

  // big neg + big neg
  BigInt a11("-2345678901234556777");
  BigInt b11("-8989898223254546364363");
  a11.Add( b11 );
  EXPECT_TRUE( a11.toString() == std::string("-8992243902155780921140") );



}

TEST(AddTest, DifFlagAdd) 
{ 
    BigInt a(-1);
    a.Add(BigInt(1));

    EXPECT_TRUE(a.toString() == std::string("0"));

    BigInt a1(1);
    a1.Add(BigInt(-1));

    EXPECT_TRUE(a1.toString() == std::string("0"));


    BigInt a2(100);
    a2.Add(BigInt(-1));
    EXPECT_TRUE( a2.toString() == std::string("99"));

    BigInt a3(-100);
    a3.Add(BigInt(1));
    EXPECT_TRUE( a3.toString() == std::string("-99"));


    BigInt a4(123);
    a4.Add(BigInt(-234));
    EXPECT_TRUE( a4.toString() == std::string("-111"));

    BigInt a5(-321);
    a5.Add(BigInt(320));
    EXPECT_TRUE( a5.toString() == std::string("-1"));

    // big neg + big pos
    BigInt a6("10000000000000000000");
    BigInt b6("-10000000000000000000");
    a6.Add(b6);
    EXPECT_TRUE( a6.toString() == std::string("0"));


    BigInt a7("20000000000000000000000");
    BigInt b7("-19999999999999999999999");
    a7.Add(b7);
    EXPECT_TRUE( a7.toString() == std::string("1"));
    

    BigInt a8("123412341234123412341234");
    BigInt b8("-98798798798798798798797");
    a8.Add(b8);
    EXPECT_TRUE( a8.toString() == std::string("24613542435324613542437"));



}


TEST(MinusTest, ZeroMinus)
{
  BigInt a(0);
  a.Minus(BigInt(1));

  EXPECT_TRUE(a.toString() == std::string("-1"));

  BigInt a1(0);
  a1.Minus(BigInt(-1));

  EXPECT_TRUE(a1.toString() == std::string("1"));


  BigInt a2(0);
  a2.Minus(BigInt(0));
  EXPECT_TRUE( a2.toString() == std::string("0"));

  BigInt a3(-100);
  a3.Minus(BigInt(0));
  EXPECT_TRUE( a3.toString() == std::string("-100"));


  BigInt a4(123);
  a4.Minus(BigInt(0));
  EXPECT_TRUE( a4.toString() == std::string("123"));



  BigInt a5("0");
  BigInt b5("1234567891011121314151617181920");
  a5.Minus(b5);
  EXPECT_TRUE( a5.toString() == std::string("-1234567891011121314151617181920"));

  
  BigInt a6("0");
  BigInt b6("1234567891011121314151617181920");
  b6.Minus( a6 );
  EXPECT_TRUE( b6.toString() == std::string("1234567891011121314151617181920") );


  BigInt a7("0");
  BigInt b7("-32432342923423472395422394014924423432336565");
  a7.Minus(b7);
  EXPECT_TRUE( a7.toString() == std::string("32432342923423472395422394014924423432336565") );

  
  BigInt a8("0");
  BigInt b8("-32432342923423472395422394014924423432336565");
  b8.Minus(a8);
  EXPECT_TRUE( b8.toString() == std::string("-32432342923423472395422394014924423432336565") );


  

}


TEST(MinusTest, SameFlagMinus)
{
  BigInt a1(10);
  BigInt b1(100);
  a1.Minus( b1 );

  EXPECT_TRUE( a1.toString() == std::string("-90"));

  BigInt a2(100);
  BigInt b2(34);
  a2.Minus(b2);

  EXPECT_TRUE( a2.toString() == std::string("66"));


  BigInt a3(99);
  BigInt b3(99);
  a3.Minus( b3 );
  EXPECT_TRUE( a3.toString() == std::string("0"));

  BigInt a4(-10);
  BigInt b4(-9);
  a4.Minus( b4);
  EXPECT_TRUE( a4.toString() == std::string("-1"));


  BigInt a5(-22);
  BigInt b5(-88);
  a5.Minus(b5);
  EXPECT_TRUE( a5.toString() == std::string("66"));


  BigInt a6(-212);
  BigInt b6(-212);
  a6.Minus(b6);
  EXPECT_TRUE( a6.toString() == std::string("0") );
  
}


TEST(MinusTest, DifFlagMinus)
{
  BigInt a0(0);
  BigInt b0("-65535");
  a0.Minus(b0);
  EXPECT_TRUE( a0.toString() == std::string("65535") ) << "true ? ";

  BigInt a1(0);
  BigInt b1("12345678910");
  a1.Minus(b1);
  EXPECT_TRUE( a1.toString() == std::string("-12345678910")) << "false ? ";

  BigInt a2(1223);
  BigInt b2(0);
  a2.Minus(b2);
  EXPECT_TRUE( a2.toString() == std::string("1223"));

  BigInt a3("-232");
  BigInt b3(0);
  a3.Minus( b3 );
  EXPECT_TRUE( a3.toString() == std::string("-232"));


  BigInt a4("123");
  BigInt b4(-877);

  a4.Minus(b4);
  EXPECT_TRUE( a4.toString() == std::string("1000"));

  BigInt a5("-20");
  BigInt b5("10");
  a5.Minus( b5 );
  EXPECT_TRUE( a5.toString() == std::string("-30"));

}


TEST(TestMultiply, ZeroMultiply)
{

  BigInt a(0);
  BigInt b("-1");
  a.Multiply(b);
  EXPECT_TRUE( a.toString() == std::string("0"));


  BigInt a0(0);
  BigInt b0(1);
  a0.Multiply(b0);
  EXPECT_TRUE( a0.toString() == std::string("0"));

  BigInt a1("-2323");
  BigInt b1("0");
  a1.Multiply(b1);
  EXPECT_TRUE( a1.toString() == std::string("0"));

  BigInt a2("2313100");
  BigInt b2("0");
  a2.Multiply(b2);
  EXPECT_TRUE( a2.toString() == std::string("0"));

  BigInt a3(0);
  BigInt b3("0");
  a3.Multiply(b3);
  EXPECT_TRUE( a3.toString() == std::string("0"));
}


TEST(TestMultiply, SameFlagMultiply)
{

  BigInt a("123456789");
  BigInt b("987654321");

  a.Multiply(b);
  EXPECT_TRUE( a.toString() == std::string("121932631112635269") );


  BigInt a1("122222222233333333");
  BigInt b1("99999999999999999999");

  a1.Multiply(b1);
  EXPECT_TRUE( a1.toString() == std::string("12222222223333333299877777777766666667") );


  BigInt a2("-999999999999998888888888888888");
  BigInt b2("-222222222333333333332211111111");

  a2.Multiply(b2);
  EXPECT_TRUE( a2.toString() == std::string("222222222333333086418630740740432100012246913703704701234568") );


  BigInt a3("98765432100292823842213654");
  BigInt b3("87");

  a3.Multiply(b3);
  EXPECT_TRUE( a3.toString() == std::string("8592592592725475674272587898") );


}


TEST(TestMultiply, DifFlagMultiply)
{
  BigInt a1("-2341");
  BigInt b1("1234");

  a1.Multiply( b1 );
  EXPECT_TRUE( a1.toString() == std::string("-2888794") );

  BigInt a2("32021314421412");
  BigInt b2("-9999999999");

  a2.Multiply(b2);
  EXPECT_TRUE( a2.toString() == std::string("-320213144182098685578588") );
}


TEST(TestDivition, ZeroDiv)
{
  BigInt a0("0");
  BigInt b0("0");

  a0.Div(b0);
  EXPECT_TRUE( a0.toString() == std::string("0") );

  BigInt a1("111111242142142412");
  BigInt b1("0");

  a1.Div(b1);
  EXPECT_TRUE( a1.toString() == std::string("111111242142142412") );

  BigInt a2("-3333333333332332325747657");
  BigInt b2("0");

  a2.Div(b2);
  EXPECT_TRUE( a2.toString() == std::string("-3333333333332332325747657") );

  BigInt a3(0);
  BigInt b3("-1231451235235235353245348898");

  a3.Div(b3);
  EXPECT_TRUE( a3.toString() == std::string("0") );

  BigInt a4(0);
  BigInt b4("9999992342344235235235353245348898");

  a4.Div(b4);
  EXPECT_TRUE( a4.toString() == std::string("0") );


}


TEST(TestDivition, SameFlagDiv)
{
  BigInt a("10");
  BigInt b("3");
  BigInt res = a.Div(b);

  EXPECT_STREQ( a.toString().c_str(), "1");
  EXPECT_STREQ( res.toString().c_str(), "3");


  BigInt a1(123);
  BigInt b1(234);
  BigInt r1 = a1.Div(b1);

  EXPECT_STREQ( a1.toString().c_str(), "123");
  EXPECT_STREQ( r1.toString().c_str(), "0");

  BigInt a2("987654321123456789");
  BigInt b2("234567");
  BigInt r2 = a2.Div(b2);

  EXPECT_STREQ( r2.toString().c_str(), "4210542493715");
  EXPECT_STREQ( a2.toString().c_str(), "210384");
  

  BigInt a3("12324124214214235325325325");
  BigInt b3("2321344444444444444444444444");
  BigInt r3 = a3.Div(b3);

  EXPECT_STREQ( r3.toString().c_str(), "0");
  EXPECT_STREQ( a3.toString().c_str(), "12324124214214235325325325");
  


}


TEST(TestDivition, DifFlagDiv)
{
  BigInt a("-32");
  BigInt b("6");
  BigInt res = a.Div(b);

  EXPECT_STREQ( a.toString().c_str(), "-2");
  EXPECT_STREQ( res.toString().c_str(), "-5");


  BigInt a0("1000");
  BigInt b0("-1000");
  BigInt r0 = a0.Div(b0);

  EXPECT_STREQ( a0.toString().c_str(), "0");
  EXPECT_STREQ( r0.toString().c_str(), "-1");
  

  BigInt a1("-1999232142354235325634646436543564546543");
  BigInt b1("3435436436457654754745746");
  BigInt r1 = a1.Div(b1);

  EXPECT_STREQ( r1.toString().c_str(), "-581944151589567");
  EXPECT_STREQ( a1.toString().c_str(), "-28399989918920733314561");
  

  BigInt a2("-128");
  BigInt b2("3");

  BigInt r2 = a2.Div(b2);

  EXPECT_STREQ( a2.toString().c_str(), "-2");
  EXPECT_STREQ( r2.toString().c_str(), "-42");
}
